package plus.lgx.textsearcher.util;


import java.io.PrintStream;
import java.util.function.Function;

/**
 * 异常处理工具类，给可能产生异常的方法一个默认值
 *
 * @param <A> 参数类型
 * @param <T> 返回值类型
 */
@SuppressWarnings("unused")
public record Throws<A, T>(Function<A, T> f, A arg, T fall) {

    public static <A, T> Throws<A, T> of(Function<A, T> f, A arg) {
        return new Throws<>(f, arg, null);
    }

    public static <A, T> Throws<A, T> of(Function<A, T> f, A arg, T fall) {
        return new Throws<>(f, arg, fall);
    }

    public static <A, T> T auto(Function<A, T> f, A arg, T fall) {
        return Throws.of(f, arg, fall).orElse();
    }

    public static <A, T> T autoPrintErr(Function<A, T> f, A arg, T fall, String format, Object... o) {
        return Throws.of(f, arg, fall).orElseErr(format, o);
    }

    public static <A, T> T autoPrintErr(Function<A, T> f, A arg, String format, Object... o) {
        return Throws.of(f, arg, null).orElseErr(format, o);
    }

    public T orElse() {
        return orElse(fall);
    }

    public T orElse(T defaultValue) {
        try {
            return f.apply(arg);
        } catch (Throwable ignored) {
            return defaultValue;
        }
    }

    public T orElsePrint(T fall, PrintStream ps, String format, Object... o) {
        try {
            return f.apply(arg);
        } catch (Throwable t) {
            ps.format(format.replaceAll("&msg", t.getMessage()), o);
            return fall;
        }
    }

    public T orElseErr(String format, Object... o) {
        try {
            return f.apply(arg);
        } catch (Throwable t) {
            System.err.format(format.replaceAll("&msg", t.getMessage()), o);
            return fall;
        }
    }
}
